using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Tools.Input;


namespace Tools.UIElements
{
    public abstract class Menu : DrawableGameComponent
    {
        #region Fields

        protected SpriteBatch sprite_batch;

        protected List<MenuEntry> entries;
        protected List<RenderableObject> renderables;
        protected IInputManager input_manager;
        #endregion

        public Menu(Game game)
            : base(game)
        {
            entries = new List<MenuEntry>();
            renderables = new List<RenderableObject>();
        }

        public void OnTap(Vector2 tap_position)
        {
            for (int i = 0; i < entries.Count; i++)
            {
                entries[i].OnTap(tap_position+offsetPosition);                
            }
        }

        public override void Initialize()
        {
            input_manager = Game.Services.GetService(typeof(IInputManager)) as IInputManager;
            if (input_manager == null)
            {
                Game.Components.Add(new InputManager(Game));
                input_manager = Game.Services.GetService(typeof(IInputManager)) as IInputManager;
            }
            input_manager.OnVerticalDrag += new InputManager.Drag(OnDrag);
            input_manager.OnDragCompleted += new InputManager.DragCompleted(OnDragCompleted);
            base.Initialize();
        }

        protected override void Dispose(bool disposing)
        {
            if (input_manager != null)
                input_manager.OnDragCompleted -= new InputManager.DragCompleted(OnDragCompleted);
            Game.Services.RemoveService(typeof(IInputManager));
            base.Dispose(disposing);
        }


        Vector2 offsetPosition = Vector2.Zero;
        public override void Update(GameTime gameTime)
        {
            for (int i = 0; i < entries.Count; i++)
            {
                entries[i].scrollOffset = offsetPosition;
            }
            
            base.Update(gameTime);
        }

        public override void  Draw(GameTime gameTime)
        {
            sprite_batch.Begin();

            for (int i = 0; i < renderables.Count; i++)
            {
                renderables[i].DrawAfterBegin();
            }

            for (int i = 0; i < entries.Count; i++)
            {
                entries[i].DrawInsideSpriteBatch();
                
            }

            sprite_batch.End();

 	        base.Draw(gameTime);
        }

        Vector2 lastDrag;
        float force = 0;
        void OnDrag(Vector2 delta)
        {
            if (!dragging)
            {
                lastDrag = delta;
            }
            dragging = true;
            force = (delta - lastDrag).Y;
            offsetPosition += Vector2.UnitY * force;
            lastDrag = delta;
        }


        bool dragging = false;
        void OnDragCompleted()
        {
            dragging = false;
        }
    }
}
